package com.ncloud.resman.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ncloud.common.utils.PageHelperUtils;
import com.ncloud.resman.constant.ResConstant;
import com.ncloud.resman.entity.Brand;
import com.ncloud.resman.entity.CpeModel;
import com.ncloud.resman.entity.FirewallModel;
import com.ncloud.resman.entity.Model;
import com.ncloud.resman.entity.ServerModel;
import com.ncloud.resman.entity.ServerUnit;
import com.ncloud.resman.entity.SwitchModel;
import com.ncloud.resman.mapper.CpeExtMapper;
import com.ncloud.resman.mapper.ModelMapper;
import com.ncloud.resman.mapper.SwitchExtMapper;
import com.ncloud.resman.service.BrandService;
import com.ncloud.resman.service.ModelService;
import com.ncloud.resman.service.SequenceService;
import com.ncloud.resman.service.ServerUnitService;

@Service
public class ModelServiceImpl implements ModelService {

	@Autowired
	private ModelMapper mapper;
	@Autowired
	private ServerUnitService serverService;
	@Autowired
	private CpeExtMapper cpeExtMapper;
	@Autowired
	private SwitchExtMapper switchMapper;
	@Autowired
	private SequenceService sequenceService;
	@Autowired
	private BrandService brandService;
	
	@Override
	public Object getModelList(JSONObject json) {
		Object object = null;
		String eqptType = json.getString("eqptType");
		Long brandId = json.getLong("brandId");
		if(PageHelperUtils.isPage(json)){
			PageHelperUtils.setPageParam(json);
			List<Map<String, Object>> modelList = mapper.findModelsByEqptTypeAndBrandId(eqptType,brandId);
			@SuppressWarnings({ "rawtypes", "unchecked" })
			PageInfo pageInfo = new PageInfo(modelList);
			object = JSON.parseObject(JSON.toJSONString(pageInfo));
		}else{
			List<Map<String, Object>> modelList = mapper.findModelsByEqptTypeAndBrandId(eqptType,brandId);
			object = JSON.parseArray(JSON.toJSONString(modelList));
		}
		return object;
	}
	
	@Override
	public JSONObject getModelById(Long modelId) {
		Model model = mapper.findModelById(modelId);
		if(model==null) return null;
		JSONObject json = JSON.parseObject(JSON.toJSONString(model));
		if(ResConstant.EQPT_TYPE_SERVER.equals(model.getEqptType())){
			List<ServerUnit> servers = serverService.getUnitListByModelId(model.getModelId());
			json.put("serverUnits", JSON.parseArray(JSON.toJSONString(servers)));
		}else if (ResConstant.EQPT_TYPE_CPE.equals(model.getEqptType())) {
			CpeModel cpeExt = cpeExtMapper.getCpeExtListByModelId(modelId);
			json.putAll(JSON.parseObject(JSON.toJSONString(cpeExt)));
		}else if (ResConstant.EQPT_TYPE_SWITCH.equals(model.getEqptType())){
			SwitchModel switchExt = switchMapper.getSwitchExtByModelId(modelId);
			json.putAll(JSON.parseObject(JSON.toJSONString(switchExt)));
		}
		return json;
	}
	
	@Override
	public Model insertModel(Model model) {
		Long modelId = sequenceService.getSequence("model_id_seq");
		model.setModelId(modelId);
		model.setState(ResConstant.MODEL_STATE_NORMAL);
		mapper.insertModel(model);
		return model;
	}
	
	@Override
	@Transactional
	public int insertServerModel(ServerModel serverModel) {
		Model model = insertModel(serverModel);
		if(serverModel.getServerUnits()!=null && !serverModel.getServerUnits().isEmpty()){
			for (ServerUnit serverUnit : serverModel.getServerUnits()) {
				serverUnit.setModelId(model.getModelId());
				serverService.insertServerUnit(serverUnit);
			}
		}
		return 1;
	}

	@Override
	@Transactional
	public int insertSwitchModel(SwitchModel switchModel) {
		Model model = insertModel(switchModel);
		switchModel.setModelId(model.getModelId());
		return switchMapper.insertSwitchModel(switchModel);
	}

	@Override
	@Transactional
	public int insertCpeModel(CpeModel cpemodel) {
		Model model = insertModel(cpemodel);
		cpemodel.setModelId(model.getModelId());
		cpeExtMapper.insertCpeExt(cpemodel);
		return 1;
	}
	
	@Override
	public int updateModel(Model model) {
		return mapper.updateModel(model);
	}
	
	@Override
	public int deleteModel(Model model) {
		Model check = mapper.findModelById(model.getModelId());
		if(check !=null) {
			model.setState(ResConstant.MODEL_STATE_DELETED);
			return mapper.deleteModel(model);
		}
		return 0;
	}

	@Override
	@Transactional
	public int updateServerModel(ServerModel serverModel) {
		updateModel(serverModel);
//		for (ServerUnit serverUnit : serverModel.getServerUnits()) {
//			serverUnit.setModelId(serverModel.getModelId());
//			if(ResConstant.MODEL_ACTION_ADD.equals(serverUnit.getModifyTag())){
//				serverService.insertServerUnit(serverUnit);
//			}else if(ResConstant.MODEL_ACTION_UPDATE.equals(serverUnit.getModifyTag())){
//				serverService.updateServerUnit(serverUnit);
//			}else if (ResConstant.MODEL_ACTION_DEL.equals(serverUnit.getModifyTag())) {
//				serverService.deleteServerUnit(serverUnit);
//			}
//		}
		// 修改为删除旧记录，插入新记录
		serverService.deleteServerUnitByModelId(serverModel.getModelId());
		if(serverModel.getServerUnits()!=null && !serverModel.getServerUnits().isEmpty()){
			for (ServerUnit serverUnit : serverModel.getServerUnits()) {
				serverUnit.setModelId(serverModel.getModelId());
				serverService.insertServerUnit(serverUnit);
			}
		}
		return 0;
	}

	@Override
	@Transactional
	public int updateSwitchModel(SwitchModel switchModel) {
		updateModel(switchModel);
		switchMapper.updateSwitchExt(switchModel);
		return 0;
	}

	@Override
	@Transactional
	public int updateCpeModel(CpeModel cpeModel) {
		updateModel(cpeModel);
		cpeExtMapper.updateCpeExt(cpeModel);
		return 0;
	}

	@Override
	public int updateFireWallModel(FirewallModel firewallModel) {
		updateModel(firewallModel);
		return 0;
	}

	@Override
	public List<Map<String, Object>> findCpeModelsByTypeAndBrandId(String eqptType, Long brandId) {
		return cpeExtMapper.getCpeModelByTypeAndBrandId(eqptType,brandId);
	}

	@Override
	public List<Map<String, Object>> findFirewallModelsByTypeAndBrandId(String eqptType, Long brandId) {
		return mapper.findModelsByEqptTypeAndBrandId(eqptType, brandId);
	}

	@Override
	public List<Map<String, Object>> findSwitchModelsByTypeAndBrandId(String eqptType, Long brandId) {
		return switchMapper.getSwitchModesByEqptTypeAndBrandId(eqptType,brandId);
	}

	@Override
	public List<Map<String, Object>> findServerModelsByTypeAndBrandId(String eqptType, Long brandId) {
		List<Map<String, Object>> resultList = new ArrayList<Map<String,Object>>();
		List<Map<String,Object>> list = mapper.findModelsByEqptTypeAndBrandId(eqptType, brandId);
		for (Map<String, Object> map : list) {
			Long modelId = (Long)map.get("modelId");
			List<ServerUnit> units = serverService.getUnitListByModelId(modelId);
			for (ServerUnit serverUnit : units) {
				if(ResConstant.UNIT_TYPE_CPU.equals(serverUnit.getUnitType())){
					map.putAll(getCpuInfo(serverUnit));
				}else if(ResConstant.UNIT_TYPE_RAM.equals(serverUnit.getUnitType())){
					map.putAll(getRamInfo(serverUnit));
				}else if(ResConstant.UNIT_TYPE_POWER.equals(serverUnit.getUnitType())){
					map.putAll(getPowerInfo(serverUnit));
				}else if(ResConstant.UNIT_TYPE_ADAPTER.equals(serverUnit.getUnitType())){
					map.putAll(getAdapterInfo(serverUnit));
				}
			}
			
			for (ServerUnit serverUnit : units) {
				if(ResConstant.UNIT_TYPE_DISK.equals(serverUnit.getUnitType())){
					map.putAll(getDiskInfo(serverUnit));
					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.putAll(map);
					resultList.add(resultMap);
				}
			}
		}
		return resultList;
	}

	private Map<String, Object> getDiskInfo(ServerUnit serverUnit) {
		Map<String, Object> map = new HashMap<String, Object>();
		Brand brand = brandService.getBrandById(serverUnit.getBrandId());
		map.put("diskBrand", brand.getBrandName());
		map.put("diskCapacity", serverUnit.getCapacity());
		map.put("diskNum", serverUnit.getAmount());
		return map;
	}

	private Map<String, Object> getCpuInfo(ServerUnit serverUnit) {
		Map<String, Object> map = new HashMap<String, Object>();
		Brand brand = brandService.getBrandById(serverUnit.getBrandId());
		map.put("cpuBrand", brand.getBrandName());
		map.put("cpuCoreNum", serverUnit.getCapacity());
		map.put("cpuNum", serverUnit.getAmount());
		return map;
	}

	private Map<String, Object> getRamInfo(ServerUnit serverUnit) {
		Map<String, Object> map = new HashMap<String, Object>();
		Brand brand = brandService.getBrandById(serverUnit.getBrandId());
		map.put("ramBrand", brand.getBrandName());
		map.put("ramCapacity", serverUnit.getCapacity());
		map.put("ramNum", serverUnit.getAmount());
		return map;
	}

	private Map<String, Object> getPowerInfo(ServerUnit serverUnit) {
		Map<String, Object> map = new HashMap<String, Object>();
		Brand brand = brandService.getBrandById(serverUnit.getBrandId());
		map.put("powerBrand", brand.getBrandName());
		map.put("powerNum", serverUnit.getAmount());
		return map;
	}

	private Map<String, Object> getAdapterInfo(ServerUnit serverUnit) {
		Map<String, Object> map = new HashMap<String, Object>();
		Brand brand = brandService.getBrandById(serverUnit.getBrandId());
		map.put("adapterBrand", brand.getBrandName());
		map.put("adapterNum", serverUnit.getAmount());
		return map;
	}

	@Override
	public Model getModelByModelName(String eqptType, Long brandId, String modelName) {
		Model model = mapper.getModelByModelName(eqptType,brandId,modelName);
		return model;
	}

	@Override
	public Model getModelInfoById(Long modelId) {
		Model model=mapper.getModelInfoById(modelId);
		return model;
	}

	@Override
	public Model getModelInfoByName(String modelName) {
		return mapper.getModelInfoByName(modelName);
	}
}
